package com.caishi.lkx.common.config;

import cn.hutool.core.util.StrUtil;
import com.zzw.common.SpringContextHolder;
import com.zzw.common.annotation.RateLimiterApi;
import com.zzw.common.exception.QPSFailException;
import com.zzw.common.gateway.limit.AbstractRateLimiterInterceptor;
import com.zzw.common.gateway.limit.QpsData;
import com.zzw.common.gateway.limit.RateLimiterApiTarget;
import com.caishi.lkx.common.context.UserContext;
import com.zzw.common.lock.RedissonLock;
import com.zzw.common.qps.spring.RedisRateLimiterBean;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.DependsOn;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.web.context.request.NativeWebRequest;
import org.springframework.web.method.HandlerMethod;

import java.util.List;

@Configuration
@Slf4j
@DependsOn("kerayRedisConfig")
public class ApiRateLimiterInterceptor extends AbstractRateLimiterInterceptor {

    private final UserContext userContext;



    // 假设 RedisTemplate 已经在另外的配置中定义
    // 确保 RedisTemplate 已经被正确配置，可以在这里直接注入

    @Autowired
    private RedisTemplate redisTemplate;

    @Bean
    @DependsOn("redisTemplate")
    public RedisRateLimiterBean redisRateLimiterBean(RedissonLock redissonLock) {
        // 创建并返回
        if (redisTemplate == null)
            redisTemplate = SpringContextHolder.getBean("redisTemplate");
        return new RedisRateLimiterBean(redissonLock, redisTemplate);
    }

    public ApiRateLimiterInterceptor(UserContext userContext) {
        this.userContext = userContext;
        log.info("注入QPS处理器");
    }

    @Override
    public void interceptor(RateLimiterApi data, NativeWebRequest request, HandlerMethod handler, List<QpsData> releaseList) throws InterruptedException, QPSFailException {
        var key = annDataGetKey(data);
        if (StrUtil.isNotEmpty(key)) {
            var qpsData = QpsData.of(data, key);
            if (data.target() == RateLimiterApiTarget.ip) {
                qpsData.setAcquireCount(userContext.currentLocalGroupId() != null ? 1 : 10);
            } else if (data.target() == RateLimiterApiTarget.user) {
                qpsData.setAcquireCount(userContext.currentLocalGroupId() != null ? 1 : 2);
            }
            this.getBean(data.bean()).acquire(qpsData.toParams());
            if (data.needRelease()) releaseList.add(qpsData);
        }
    }

}
